package solver;

import java.util.Random;

public class Results {
	private static Random random = new Random();
	public boolean isConflict;
	public float[][] psi; // state of world random variables
	public  boolean[][] winners; // winners
	public float[][] v; // probability of winning
	public float[][] theta;
	public float[] utility;
	public float[] utility_bar;
	public static double epsilon = 1E-99;
	
	public Results() {
		isConflict = false;
	}
	
	public boolean isWinner(int i, int j) {
		return winners[i][j];
	}
	
	public boolean isConflict() {
		return isConflict;
	}
	
	public float[][] getThetasF() {
		float[][] out = new float[theta.length][theta.length];
		for (int i = 0; i<theta.length; i++) {
			for (int j = 0; j<theta.length; j++) {
				out[i][j] = theta[i][j];
			}
		}
		return out;
	}
	
	public double[][] getThetasD() {
		double[][] out = new double[theta.length][theta.length];
		for (int i = 0; i<theta.length; i++) {
			for (int j = 0; j<theta.length; j++) {
				out[i][j] = theta[i][j];
			}
		}
		return out;
	}
	
	public float[] getUtility() {
		float[] out = new float[psi.length];
		for (int i=0; i<utility.length; i++) {
			out[i] = utility[i];
		}
		return out;
	}
	
	/**
	 * @return the psi
	 */
	public float[][] getPsi() {
		float[][] out = new float[psi.length][psi.length];
		for (int i=0; i<psi.length; i++) {
			for (int j=0; j<psi.length; j++) {
				out[i][j] = psi[i][j];
			}
		}
		return out;
	}
	
	/**
	 * @return the winners
	 */
	public boolean[][] getWinners() {
		boolean[][] out = new boolean[winners.length][winners.length];
		for (int i=0; i<winners.length; i++) {
			for (int j=0; j<winners.length; j++) {
				out[i][j] = winners[i][j];
			}
		}
		return out;
	}
	
	/**
	 * @return the prob_win
	 */
	public float[][] getV() {
		float[][] out = new float[v.length][v.length];
		for (int i=0; i<v.length; i++) {
			for (int j=0; j<v.length; j++) {
				out[i][j] = v[i][j];
			}
		}
		return out;
	}
	
	public Results(double I, float[][] theta, float[] utility, float[] utility_bar) {
		random.setSeed(System.nanoTime());
		float rand1 = random.nextFloat();

		int L = theta.length;

		this.theta = new float[L][L];
		this.utility = new float[L];
		this.utility_bar = new float[L];
		this.psi = new float[L][L];
		this.v = new float[L][L];
		this.winners = new boolean[L][L];
		
		this.theta = new float[L][L];
		for (int i=0; i<L; i++) {
			for (int j=0; j<L; j++) {
				this.theta[i][j] = theta[i][j];
			}
		}
		for (int i=0; i<psi.length; i++) {
   		  this.utility[i] = utility[i];
		  this.utility_bar[i] = utility_bar[i];
	    }			

		
		if (rand1 <= I) { // no conflict, suppressed by institutions
		  isConflict = false;
			//TODO: Make sure Leo doesn't need any more data if no conflict
		} else { // uh oh.
			isConflict = true;
			this.psi = calcPSI(theta);
			this.v = rollDice(L);
			this.winners = new boolean[L][L];
			
			for (int i=0; i<psi.length; i++) {
				for (int j=i; j<psi.length; j++) {
					if (i==j) {
						winners[i][j] = true;
						continue;
					}
					//TODO: might need boundary condition in case of tie
					if (v[i][j] <= psi[i][j]) {
						winners[i][j] = true;
						winners[j][i] = false;
					} else {
						winners[i][j] = false;
						winners[j][i] = true;
					}
				}
			}			
		}

		
	}
	
	private static float[][] calcPSI(float[][] thetas) {
		int L = thetas.length;
		float[][] psi = new float[L][L];
		for (int i=0; i<L; i++) {
			for (int j=0; j<L; j++) {
				if (i == j) {
					psi[i][j] = 0;
					continue;
				}
				psi[i][j] = (float)(thetas[i][j] / (epsilon+thetas[i][j]+thetas[j][i]));
			}
		}
		return psi;
	}

	private static float[][] rollDice(int n) {
		float[][] out = new float[n][n];
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				out[i][j] = random.nextFloat();
			}
		}
		return out;
	}

	
}
